package org.dromara.nursing.service.impl;

import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.dromara.nursing.domain.bo.ElderOutstandingFeesBo;
import org.dromara.nursing.domain.vo.ElderOutstandingFeesVo;
import org.dromara.nursing.domain.ElderOutstandingFees;
import org.dromara.nursing.mapper.ElderOutstandingFeesMapper;
import org.dromara.nursing.service.IElderOutstandingFeesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 欠费记录Service业务层处理
 *
 * @author Xue
 * @date 2025-04-09
 */
@RequiredArgsConstructor
@Service
public class ElderOutstandingFeesServiceImpl implements IElderOutstandingFeesService {

    private final ElderOutstandingFeesMapper baseMapper;
    private static final Logger log = LoggerFactory.getLogger(ElderOutstandingFeesServiceImpl.class);

    /**
     * 查询欠费记录
     *
     * @param recordId 主键
     * @return 欠费记录
     */
    @Override
    public ElderOutstandingFeesVo queryById(Long recordId){
        return baseMapper.selectVoById(recordId);
    }

    /**
     * 分页查询欠费记录列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 欠费记录分页列表
     */
    @Override
    public TableDataInfo<ElderOutstandingFeesVo> queryPageList(ElderOutstandingFeesBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ElderOutstandingFees> lqw = buildQueryWrapper(bo);
        Page<ElderOutstandingFeesVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 分页查询按老人汇总的欠费记录列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 按老人汇总的欠费记录分页列表
     */
    @Override
    public TableDataInfo<ElderOutstandingFeesVo> querySummaryPageList(ElderOutstandingFeesBo bo, PageQuery pageQuery) {
        // 先获取所有符合条件的记录
        List<ElderOutstandingFeesVo> allRecords = queryList(bo);

        // 按老人ID和姓名分组汇总
        Map<String, ElderOutstandingFeesVo> summaryMap = new java.util.HashMap<>();

        for (ElderOutstandingFeesVo record : allRecords) {
            String key = record.getElderName(); // 使用老人姓名作为键

            if (summaryMap.containsKey(key)) {
                // 已存在该老人的汇总记录，累加金额
                ElderOutstandingFeesVo summary = summaryMap.get(key);

                // 累加金额
                if (summary.getTotalAmount() != null && record.getTotalAmount() != null) {
                    summary.setTotalAmount(summary.getTotalAmount() + record.getTotalAmount());
                }

                if (summary.getPaidAmount() != null && record.getPaidAmount() != null) {
                    Long summaryPaid = Long.valueOf(summary.getPaidAmount().toString());
                    Long recordPaid = Long.valueOf(record.getPaidAmount().toString());
                    summary.setPaidAmount(summaryPaid + recordPaid);
                }

                if (summary.getOutstandingAmount() != null && record.getOutstandingAmount() != null) {
                    summary.setOutstandingAmount(summary.getOutstandingAmount() + record.getOutstandingAmount());
                }

                // 更新日期为最新日期
                if (record.getBillDate() != null && (summary.getBillDate() == null ||
                    record.getBillDate().after(summary.getBillDate()))) {
                    summary.setBillDate(record.getBillDate());
                }

                if (record.getDueDate() != null && (summary.getDueDate() == null ||
                    record.getDueDate().after(summary.getDueDate()))) {
                    summary.setDueDate(record.getDueDate());
                }

            } else {
                // 创建新的汇总记录
                ElderOutstandingFeesVo summary = new ElderOutstandingFeesVo();
                summary.setElderName(record.getElderName());
                summary.setTotalAmount(record.getTotalAmount());
                summary.setPaidAmount(record.getPaidAmount());
                summary.setOutstandingAmount(record.getOutstandingAmount());
                summary.setBillDate(record.getBillDate());
                summary.setDueDate(record.getDueDate());

                summaryMap.put(key, summary);
            }
        }

        // 计算支付状态
        for (ElderOutstandingFeesVo summary : summaryMap.values()) {
            if (summary.getOutstandingAmount() != null && summary.getTotalAmount() != null) {
                if (summary.getOutstandingAmount() == 0) {
                    summary.setPaymentStatus("已支付");
                } else if (summary.getOutstandingAmount().equals(summary.getTotalAmount())) {
                    summary.setPaymentStatus("未支付");
                } else {
                    summary.setPaymentStatus("部分支付");
                }
            }
        }

        // 转换为列表并排序
        List<ElderOutstandingFeesVo> summaryList = new java.util.ArrayList<>(summaryMap.values());
        summaryList.sort((a, b) -> {
            if (a.getOutstandingAmount() == null) return 1;
            if (b.getOutstandingAmount() == null) return -1;
            return b.getOutstandingAmount().compareTo(a.getOutstandingAmount());
        });

        // 手动分页
        int pageSize = pageQuery.getPageSize();
        int pageNum = pageQuery.getPageNum();
        int total = summaryList.size();

        int fromIndex = (pageNum - 1) * pageSize;
        if (fromIndex >= total) {
            fromIndex = 0;
            pageNum = 1;
        }

        int toIndex = Math.min(fromIndex + pageSize, total);
        List<ElderOutstandingFeesVo> pageData = summaryList.subList(fromIndex, toIndex);

        // 构建分页结果
        Page<ElderOutstandingFeesVo> page = new Page<>(pageNum, pageSize, total);
        page.setRecords(pageData);

        return TableDataInfo.build(page);
    }

    /**
     * 查询符合条件的欠费记录列表
     *
     * @param bo 查询条件
     * @return 欠费记录列表
     */
    @Override
    public List<ElderOutstandingFeesVo> queryList(ElderOutstandingFeesBo bo) {
        LambdaQueryWrapper<ElderOutstandingFees> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 查询符合条件的按老人汇总的欠费记录列表
     *
     * @param bo 查询条件
     * @return 按老人汇总的欠费记录列表
     */
    @Override
    public List<ElderOutstandingFeesVo> querySummaryList(ElderOutstandingFeesBo bo) {
        // 先获取所有符合条件的记录
        List<ElderOutstandingFeesVo> allRecords = queryList(bo);

        // 按老人ID和姓名分组汇总
        Map<String, ElderOutstandingFeesVo> summaryMap = new java.util.HashMap<>();

        for (ElderOutstandingFeesVo record : allRecords) {
            String key = record.getElderName(); // 使用老人姓名作为键

            if (summaryMap.containsKey(key)) {
                // 已存在该老人的汇总记录，累加金额
                ElderOutstandingFeesVo summary = summaryMap.get(key);

                // 累加金额
                if (summary.getTotalAmount() != null && record.getTotalAmount() != null) {
                    summary.setTotalAmount(summary.getTotalAmount() + record.getTotalAmount());
                }

                if (summary.getPaidAmount() != null && record.getPaidAmount() != null) {
                    Long summaryPaid = Long.valueOf(summary.getPaidAmount().toString());
                    Long recordPaid = Long.valueOf(record.getPaidAmount().toString());
                    summary.setPaidAmount(summaryPaid + recordPaid);
                }

                if (summary.getOutstandingAmount() != null && record.getOutstandingAmount() != null) {
                    summary.setOutstandingAmount(summary.getOutstandingAmount() + record.getOutstandingAmount());
                }

                // 更新日期为最新日期
                if (record.getBillDate() != null && (summary.getBillDate() == null ||
                    record.getBillDate().after(summary.getBillDate()))) {
                    summary.setBillDate(record.getBillDate());
                }

                if (record.getDueDate() != null && (summary.getDueDate() == null ||
                    record.getDueDate().after(summary.getDueDate()))) {
                    summary.setDueDate(record.getDueDate());
                }

            } else {
                // 创建新的汇总记录
                ElderOutstandingFeesVo summary = new ElderOutstandingFeesVo();
                summary.setElderName(record.getElderName());
                summary.setTotalAmount(record.getTotalAmount());
                summary.setPaidAmount(record.getPaidAmount());
                summary.setOutstandingAmount(record.getOutstandingAmount());
                summary.setBillDate(record.getBillDate());
                summary.setDueDate(record.getDueDate());

                summaryMap.put(key, summary);
            }
        }

        // 计算支付状态
        for (ElderOutstandingFeesVo summary : summaryMap.values()) {
            if (summary.getOutstandingAmount() != null && summary.getTotalAmount() != null) {
                if (summary.getOutstandingAmount() == 0) {
                    summary.setPaymentStatus("已支付");
                } else if (summary.getOutstandingAmount().equals(summary.getTotalAmount())) {
                    summary.setPaymentStatus("未支付");
                } else {
                    summary.setPaymentStatus("部分支付");
                }
            }
        }

        // 转换为列表并排序
        List<ElderOutstandingFeesVo> summaryList = new java.util.ArrayList<>(summaryMap.values());
        summaryList.sort((a, b) -> {
            if (a.getOutstandingAmount() == null) return 1;
            if (b.getOutstandingAmount() == null) return -1;
            return b.getOutstandingAmount().compareTo(a.getOutstandingAmount());
        });

        return summaryList;
    }

    private LambdaQueryWrapper<ElderOutstandingFees> buildQueryWrapper(ElderOutstandingFeesBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ElderOutstandingFees> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(ElderOutstandingFees::getRecordId);
        lqw.like(StringUtils.isNotBlank(bo.getElderName()), ElderOutstandingFees::getElderName, bo.getElderName());
        lqw.eq(StringUtils.isNotBlank(bo.getFeeSource()), ElderOutstandingFees::getFeeSource, bo.getFeeSource());
        lqw.eq(bo.getSourceId() != null, ElderOutstandingFees::getSourceId, bo.getSourceId());
        return lqw;
    }

    /**
     * 新增欠费记录
     *
     * @param bo 欠费记录
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(ElderOutstandingFeesBo bo) {
        log.info("开始新增欠费记录: elderID={}, elderName={}, sourceID={}, feeSource={}, paymentStatus={}, 总金额={}, 已付金额={}, 未付金额={}",
                bo.getElderId(), bo.getElderName(), bo.getSourceId(), bo.getFeeSource(),
                bo.getPaymentStatus(), bo.getTotalAmount(), bo.getPaidAmount(), bo.getOutstandingAmount());

        try {
            // 在插入前，先查询是否已存在同一老人同一费用类型的欠费记录
            ElderOutstandingFeesBo queryBo = new ElderOutstandingFeesBo();
            queryBo.setElderId(bo.getElderId());
            queryBo.setFeeSource(bo.getFeeSource());

            // 不同的来源ID，只合并同类型的费用
            if (bo.getSourceId() != null) {
                queryBo.setSourceId(null); // 不按来源ID查询，只按老人和费用类型
            }

            List<ElderOutstandingFeesVo> existingRecords = queryList(queryBo);
            log.info("查询到现有欠费记录: {}", existingRecords.size());

            if (!existingRecords.isEmpty()) {
                // 找到现有记录，更新它
                ElderOutstandingFeesVo existingRecord = existingRecords.get(0);
                log.info("找到现有欠费记录，ID: {}, 当前总金额: {}, 当前欠费金额: {}",
                        existingRecord.getRecordId(), existingRecord.getTotalAmount(), existingRecord.getOutstandingAmount());

                ElderOutstandingFeesBo updateBo = new ElderOutstandingFeesBo();
                updateBo.setRecordId(existingRecord.getRecordId());

                // 计算新的金额
                Long newTotalAmount = existingRecord.getTotalAmount() + bo.getTotalAmount();
                Long newOutstandingAmount = null;
                if (existingRecord.getOutstandingAmount() != null && bo.getOutstandingAmount() != null) {
                    newOutstandingAmount = existingRecord.getOutstandingAmount() + bo.getOutstandingAmount();
                } else if (bo.getOutstandingAmount() != null) {
                    newOutstandingAmount = bo.getOutstandingAmount();
                } else {
                    newOutstandingAmount = existingRecord.getOutstandingAmount();
                }

                updateBo.setTotalAmount(newTotalAmount);
                updateBo.setOutstandingAmount(newOutstandingAmount);

                // 更新费用描述，添加新来源ID
                // 注释掉这段代码，不再向fee_description字段中累加记录ID，避免数据过长问题
                /*
                String newDescription = existingRecord.getFeeDescription();
                if (StringUtils.isNotBlank(newDescription)) {
                    newDescription += ", " + bo.getSourceId();
                } else {
                    newDescription = String.valueOf(bo.getSourceId());
                }
                updateBo.setFeeDescription(newDescription);
                */

                log.info("更新欠费记录，新总金额: {}, 新欠费金额: {}", newTotalAmount, newOutstandingAmount);

                return updateByBo(updateBo);
            } else {
                // 没有现有记录，创建新记录
                ElderOutstandingFees add = MapstructUtils.convert(bo, ElderOutstandingFees.class);
                validEntityBeforeSave(add);

                boolean flag = baseMapper.insert(add) > 0;
                if (flag) {
                    bo.setRecordId(add.getRecordId());
                    log.info("欠费记录新增成功，ID: {}", bo.getRecordId());
                } else {
                    log.error("欠费记录新增失败");
                }
                return flag;
            }
        } catch (Exception e) {
            log.error("新增/更新欠费记录异常: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 修改欠费记录
     *
     * @param bo 欠费记录
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(ElderOutstandingFeesBo bo) {
        log.info("开始修改欠费记录: recordID={}, elderID={}, paymentStatus={}, 已付金额={}, 未付金额={}",
                bo.getRecordId(), bo.getElderId(), bo.getPaymentStatus(), bo.getPaidAmount(), bo.getOutstandingAmount());

        ElderOutstandingFees update = MapstructUtils.convert(bo, ElderOutstandingFees.class);
        validEntityBeforeSave(update);
        try {
            boolean result = baseMapper.updateById(update) > 0;
            if (result) {
                log.info("欠费记录修改成功");
            } else {
                log.error("欠费记录修改失败");
            }
            return result;
        } catch (Exception e) {
            log.error("修改欠费记录异常: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ElderOutstandingFees entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除欠费记录信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
